home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 22 / PCPP #22.iso / Quake2 / q2source_12_11 / utils3 / bsp / qbsp3 / prtfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-19  |  5.4 KB  |  267 lines

  1.  
  2. #include "qbsp.h"
  3.  
  4. /*
  5. ==============================================================================
  6.  
  7. PORTAL FILE GENERATION
  8.  
  9. Save out name.prt for qvis to read
  10. ==============================================================================
  11. */
  12.  
  13.  
  14. #define    PORTALFILE    "PRT1"
  15.  
  16. FILE    *pf;
  17. int        num_visclusters;                // clusters the player can be in
  18. int        num_visportals;
  19.  
  20. void WriteFloat (FILE *f, vec_t v)
  21. {
  22.     if ( fabs(v - Q_rint(v)) < 0.001 )
  23.         fprintf (f,"%i ",(int)Q_rint(v));
  24.     else
  25.         fprintf (f,"%f ",v);
  26. }
  27.  
  28. /*
  29. =================
  30. WritePortalFile_r
  31. =================
  32. */
  33. void WritePortalFile_r (node_t *node)
  34. {
  35.     int            i, s;    
  36.     portal_t    *p;
  37.     winding_t    *w;
  38.     vec3_t        normal;
  39.     vec_t        dist;
  40.  
  41.     // decision node
  42.     if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
  43.     {
  44.         WritePortalFile_r (node->children[0]);
  45.         WritePortalFile_r (node->children[1]);
  46.         return;
  47.     }
  48.     
  49.     if (node->contents & CONTENTS_SOLID)
  50.         return;
  51.  
  52.     for (p = node->portals ; p ; p=p->next[s])
  53.     {
  54.         w = p->winding;
  55.         s = (p->nodes[1] == node);
  56.         if (w && p->nodes[0] == node)
  57.         {
  58.             if (!Portal_VisFlood (p))
  59.                 continue;
  60.         // write out to the file
  61.         
  62.         // sometimes planes get turned around when they are very near
  63.         // the changeover point between different axis.  interpret the
  64.         // plane the same way vis will, and flip the side orders if needed
  65.             // FIXME: is this still relevent?
  66.             WindingPlane (w, normal, &dist);
  67.             if ( DotProduct (p->plane.normal, normal) < 0.99 )
  68.             {    // backwards...
  69.                 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster);
  70.             }
  71.             else
  72.                 fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster);
  73.             for (i=0 ; i<w->numpoints ; i++)
  74.             {
  75.                 fprintf (pf,"(");
  76.                 WriteFloat (pf, w->p[i][0]);
  77.                 WriteFloat (pf, w->p[i][1]);
  78.                 WriteFloat (pf, w->p[i][2]);
  79.                 fprintf (pf,") ");
  80.             }
  81.             fprintf (pf,"\n");
  82.         }
  83.     }
  84.  
  85. }
  86.  
  87. /*
  88. ================
  89. FillLeafNumbers_r
  90.  
  91. All of the leafs under node will have the same cluster
  92. ================
  93. */
  94. void FillLeafNumbers_r (node_t *node, int num)
  95. {
  96.     if (node->planenum == PLANENUM_LEAF)
  97.     {
  98.         if (node->contents & CONTENTS_SOLID)
  99.             node->cluster = -1;
  100.         else
  101.             node->cluster = num;
  102.         return;
  103.     }
  104.     node->cluster = num;
  105.     FillLeafNumbers_r (node->children[0], num);
  106.     FillLeafNumbers_r (node->children[1], num);
  107. }
  108.  
  109. /*
  110. ================
  111. NumberLeafs_r
  112. ================
  113. */
  114. void NumberLeafs_r (node_t *node)
  115. {
  116.     portal_t    *p;
  117.  
  118.     if (node->planenum != PLANENUM_LEAF && !node->detail_seperator)
  119.     {    // decision node
  120.         node->cluster = -99;
  121.         NumberLeafs_r (node->children[0]);
  122.         NumberLeafs_r (node->children[1]);
  123.         return;
  124.     }
  125.     
  126.     // either a leaf or a detail cluster
  127.  
  128.     if ( node->contents & CONTENTS_SOLID )
  129.     {    // solid block, viewpoint never inside
  130.         node->cluster = -1;
  131.         return;
  132.     }
  133.  
  134.     FillLeafNumbers_r (node, num_visclusters);
  135.     num_visclusters++;
  136.  
  137.     // count the portals
  138.     for (p = node->portals ; p ; )
  139.     {
  140.         if (p->nodes[0] == node)        // only write out from first leaf
  141.         {
  142.             if (Portal_VisFlood (p))
  143.                 num_visportals++;
  144.             p = p->next[0];
  145.         }
  146.         else
  147.             p = p->next[1];        
  148.     }
  149.  
  150. }
  151.  
  152.  
  153. /*
  154. ================
  155. CreateVisPortals_r
  156. ================
  157. */
  158. void CreateVisPortals_r (node_t *node)
  159. {
  160.     // stop as soon as we get to a detail_seperator, which
  161.     // means that everything below is in a single cluster
  162.     if (node->planenum == PLANENUM_LEAF || node->detail_seperator )
  163.         return;
  164.  
  165.     MakeNodePortal (node);
  166.     SplitNodePortals (node);
  167.  
  168.     CreateVisPortals_r (node->children[0]);
  169.     CreateVisPortals_r (node->children[1]);
  170. }
  171.  
  172. /*
  173. ================
  174. FinishVisPortals_r
  175. ================
  176. */
  177. void FinishVisPortals2_r (node_t *node)
  178. {
  179.     if (node->planenum == PLANENUM_LEAF)
  180.         return;
  181.  
  182.     MakeNodePortal (node);
  183.     SplitNodePortals (node);
  184.  
  185.     FinishVisPortals2_r (node->children[0]);
  186.     FinishVisPortals2_r (node->children[1]);
  187. }
  188.  
  189. void FinishVisPortals_r (node_t *node)
  190. {
  191.     if (node->planenum == PLANENUM_LEAF)
  192.         return;
  193.  
  194.     if (node->detail_seperator)
  195.     {
  196.         FinishVisPortals2_r (node);
  197.         return;
  198.     }
  199.  
  200.     FinishVisPortals_r (node->children[0]);
  201.     FinishVisPortals_r (node->children[1]);
  202. }
  203.  
  204.  
  205. int        clusterleaf;
  206. void SaveClusters_r (node_t *node)
  207. {
  208.     if (node->planenum == PLANENUM_LEAF)
  209.     {
  210.         dleafs[clusterleaf++].cluster = node->cluster;
  211.         return;
  212.     }
  213.     SaveClusters_r (node->children[0]);
  214.     SaveClusters_r (node->children[1]);
  215. }
  216.  
  217. /*
  218. ================
  219. WritePortalFile
  220. ================
  221. */
  222. void WritePortalFile (tree_t *tree)
  223. {
  224.     char    filename[1024];
  225.     node_t *headnode;
  226.  
  227.     qprintf ("--- WritePortalFile ---\n");
  228.  
  229.     headnode = tree->headnode;
  230.     num_visclusters = 0;
  231.     num_visportals = 0;
  232.  
  233.     FreeTreePortals_r (headnode);
  234.  
  235.     MakeHeadnodePortals (tree);
  236.  
  237.     CreateVisPortals_r (headnode);
  238.  
  239. // set the cluster field in every leaf and count the total number of portals
  240.  
  241.     NumberLeafs_r (headnode);
  242.     
  243. // write the file
  244.     sprintf (filename, "%s.prt", source);
  245.     printf ("writing %s\n", filename);
  246.     pf = fopen (filename, "w");
  247.     if (!pf)
  248.         Error ("Error opening %s", filename);
  249.         
  250.     fprintf (pf, "%s\n", PORTALFILE);
  251.     fprintf (pf, "%i\n", num_visclusters);
  252.     fprintf (pf, "%i\n", num_visportals);
  253.  
  254.     qprintf ("%5i visclusters\n", num_visclusters);
  255.     qprintf ("%5i visportals\n", num_visportals);
  256.  
  257.     WritePortalFile_r (headnode);
  258.  
  259.     fclose (pf);
  260.  
  261.     // we need to store the clusters out now because ordering
  262.     // issues made us do this after writebsp...
  263.     clusterleaf = 1;
  264.     SaveClusters_r (headnode);
  265. }
  266.  
  267.